package com.cardone.common.function;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import com.cardone.common.util.CipherUtils;
import com.cardone.context.function.Execution2Function;

@Slf4j
public class CreateZipFileFunction implements Execution2Function<String, String, String> {
	public static void main(final String[] args) {
		final String filepath = new CreateZipFileFunction().execution("d:\\temps\\applicationContext-dataSource.xml", "123456");

		System.out.println(filepath);
	}

	@Override
	public String execution(final String filename, final String password) {
		final String zipFullPath = FilenameUtils.getFullPath(filename);

		final String zipBaseName = FilenameUtils.getBaseName(filename);

		final String zipExtension = "zip";

		final String zipFilename = StringUtils.join(new String[] { zipFullPath, zipBaseName, ".", zipExtension });

		final String zipTempFilename = StringUtils.join(new String[] { zipFullPath, zipBaseName, "_temp.", zipExtension });

		final String name = FilenameUtils.getName(filename);

		final int bufferLen = 1024 * 1024;

		InputStream is = null;
		ZipArchiveOutputStream out = null;

		try {
			is = new BufferedInputStream(new FileInputStream(filename), bufferLen);

			out = new ZipArchiveOutputStream(new BufferedOutputStream(new FileOutputStream(zipTempFilename), bufferLen));

			final ZipArchiveEntry entry = new ZipArchiveEntry(name);

			out.putArchiveEntry(entry);

			IOUtils.copy(is, out);

			out.closeArchiveEntry();
		} catch (final IOException e) {
			CreateZipFileFunction.log.error(e.getMessage(), e);
		} finally {
			IOUtils.closeQuietly(is);
			IOUtils.closeQuietly(out);
		}

		try {
			CipherUtils.encrypt(zipTempFilename, zipFilename, password);
		} catch (GeneralSecurityException | IOException e) {
			CreateZipFileFunction.log.error(e.getMessage(), e);
		} finally {
			FileUtils.deleteQuietly(new File(zipTempFilename));
		}

		return zipFilename;
	}
}
